import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter_ume_kit_mock/data/model/mock_history.dart';
import 'package:flutter_ume_kit_mock/util/json_tamper.dart';
import 'package:flutter_ume_kit_mock/util/time_util.dart';

import 'package:flutter_ume_kit_mock/data/mock_config_manager.dart';
import 'package:flutter_ume_kit_mock/data/model/mock.dart';
import 'package:flutter_ume_kit_mock/widgets/mock_inspector.dart';

class MockInterceptor extends Interceptor {
  @override
  void onRequest(
      RequestOptions options, RequestInterceptorHandler handler) async {
    await MockConfigManager.waitCompleteInitConfig();
    String? mockResponse = await _checkFakeRequestMock(options);
    if (mockResponse == null) {
      super.onRequest(options, handler);
    } else {
      //响应里添加标识，区分是否是被mock的请求
      if (mockResponse.startsWith("{")) {
        mockResponse = mockResponse.replaceRange(0, 1, '{"isMocked":true,');
      }
      var response = Response(
          data: mockResponse, requestOptions: options, statusCode: 200);
      handler.resolve(response, true);
    }
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    bool mockDelayed = response.requestOptions.extra['mockDelayed'] == true;
    if (response.statusCode == 200 && response.data != null) {
      Mock? mock = _findTargetMock(response.requestOptions);
      if (mock?.fields?.tamper != null) {
        var tamperMap = jsonDecode(mock!.fields!.tamper!);
        if (tamperMap is Map) {
          tamperMap['isTampered'] = true;
          response.data = JsonEditor.editJson(response.data, tamperMap);
          //触发修改，提示红点
          MockConfigManager.triggerStreamController.sink.add(MockHistory(
              mock, DateTime.now().toHms(),
              tamper: true, delayed: mockDelayed));
        }
      } else if (mockDelayed && mock != null) {
        //触发修改，提示红点
        MockConfigManager.triggerStreamController.sink
            .add(MockHistory(mock, DateTime.now().toHms(), delayed: true));
      }
    }
    super.onResponse(response, handler);
  }

  Future<String?> _checkFakeRequestMock(RequestOptions options) async {
    Mock? mock = _findTargetMock(options);
    if (mock == null) {
      return null;
    }
    int delay = mock.fields?.delay ?? 0;
    //触发mock，显示红点
    if (mock.fields?.response != null) {
      MockConfigManager.triggerStreamController.sink.add(MockHistory(
          mock, DateTime.now().toHms(),
          delayed: delay > 0, fake: mock.fields?.response != null));
    } else {
      options.extra['mockDelayed'] = delay > 0;
    }

    if (delay > 0) {
      return Future.delayed(Duration(milliseconds: delay), () {
        return mock.fields?.response;
      });
    } else {
      return mock.fields?.response;
    }
  }

  ///找出匹配的mock
  Mock? _findTargetMock(RequestOptions options) {
    var gatherEnableMocks = _gatherEnableMocks();
    for (var mock in gatherEnableMocks) {
      if (mock.request?.fields?.path == options.path &&
          mock.request?.fields?.method == options.method.toUpperCase()) {
        if (mock.fields?.condition == null || mock.fields!.condition!.isEmpty) {
          print(
              "${MockInspector.TAG} match mock ${options.path}   ${mock.fields?.title}");
          return mock;
        } else {
          if (_checkCondition(options, mock.fields!.condition!)) {
            print(
                "${MockInspector.TAG} match mock ${options.path}   ${mock.fields?.title}");
            return mock;
          }
        }
      }
    }
    return null;
  }

  ///检查请求参数是否符合配置要求
  bool _checkCondition(RequestOptions options, String condition) {
    try {
      Map<String, dynamic> conditionMap = jsonDecode(condition);
      Map<String, dynamic>? requestParams =
          options.method.toUpperCase() == "GET"
              ? options.queryParameters
              : options.data;

      bool allMatch = true;
      for (var entity in conditionMap.entries) {
        print(
            "${MockInspector.TAG} checkCondition ${entity.key}:${entity.value}    ${requestParams?[entity.key]}");
        if (entity.value.toString() != requestParams?[entity.key].toString()) {
          allMatch = false;
          break;
        }
      }
      return allMatch;
    } catch (e) {
      print("${MockInspector.TAG} checkCondition ${e}");
    }
    return false;
  }

  List<Mock> _gatherEnableMocks() {
    List<Mock> list = [];
    for (var mockCase in MockConfigManager.caseListNotifier.value) {
      if (mockCase.enable && mockCase.mocks != null) {
        list.addAll(mockCase.mocks!);
      }
    }
    for (var mock in MockConfigManager.mockListNotifier.value) {
      if (mock.enable) {
        list.add(mock);
      }
    }
    return list;
  }
}
